dofile( "GEO\\gsgeo.lua" ) -- load GEO SDK
if not G then error( "GEO SDK Failed to load, cannot continue." ) end
do
	
	local constant, max_generations = 0.7, 5
	local growth_spread = 0.9
	
	local create_line, line_logic, render_line
	
	math.randomseed( os.time() )
	
	local G,gs=_G.G,_G.gs
	
	G.core.with( G.render:newPass(), {
		
		beforeRender = function()
			gs.resetCamera()
			gs.render_resetmatrix()
			gs.render_lookat( 0, 0, 0,  0, 0, -1,  0, 1, 0 )
			gs.render_clearbuffer()
			
			gs.render_glbegin_lines()
			return true
		end;
		
		afterRender = function()
			gs.render_glend()
			gs.render_flush()
		end
	})
	
	render_line = function(entRender, pass)
		local ent = entRender.ent
		local pent = ent._parent
		
		if G.core.is_ent(pent) then
			gs.render_color(pent.cr, pent.cg, pent.cb, 1.0)
		else
			gs.render_color(ent.cr, ent.cg, ent.cb, 1.0)
		end
		
		gs.render_vertex(
			ent.pos_x,
			ent.pos_y,
			ent.pos_z
		)
		
		gs.render_color(ent.cr, ent.cg, ent.cb, 1.0)
		
		gs.render_vertex(
			ent.pos_x + ent.dir_x * ent.length,
			ent.pos_y + ent.dir_y * ent.length,
			ent.pos_z + ent.dir_z * ent.length
		)
		
		return true
	end
	
	
	line_logic = function( frame )
		
		local line = frame._parent.ent
		
		line.length = line.length + (  line.param * math.random() ) * DELTA
		
		if line.length >= line.param then
			
			line.length = line.param
			
			if line.generation < max_generations then
				for i = 1,12 do create_line( line ) end
			end
			
			
			return false
		else
			
			return true
			
		end
		
	end
	
	create_line = function( parent_line )
		local line = G.core.newEnt()
		
		if G.core.is_ent(parent_line) then
			
			local dx, dz = parent_line.dir_x + growth_spread * (2*math.random() - 1), parent_line.dir_z + growth_spread * (2*math.random() - 1)
			
			local dy = math.sqrt(dx*dx + dz*dz)
			
			if dy == 0 then
				dx,dy,dz = 0,1,0
			else
				dx, dz = dx / dy, dz / dy
				dy = math.sqrt(1 - dx*dx - dz*dz)
			end
			
			local c = {
				generation = parent_line.generation + 1,
				param = parent_line.param * constant,
				length = 0,
				
				cr = math.random() * 0.5 + 0.25,
				cg = math.random() * 0.5 + 0.25,
				cb = math.random() * 0.5 + 0.25,
				
				pos_x = parent_line.pos_x + parent_line.dir_x * parent_line.length,
				pos_y = parent_line.pos_y + parent_line.dir_y * parent_line.length,
				pos_z = parent_line.pos_z + parent_line.dir_z * parent_line.length,
				
				dir_x = dx,
				dir_y = dy,
				dir_z = dz
				
			}
			
			G.core.with( line, c ):moveto( G )
			
			line.state:newFrame{step = line_logic}:activate()
			
		else
			
			local c = {
				generation = 1,
				param = 3,
				length = 0,
				
				cr = math.random() * 0.5 + 0.25,
				cg = math.random() * 0.5 + 0.25,
				cb = math.random() * 0.5 + 0.25,
				
				pos_x = 0,
				pos_y = -2,
				pos_z = -6,
				
				dir_x = 0,
				dir_y = 1,
				dir_z = 0
			}
			
			G.core.with( line, c)
			
			line.state:newFrame{step = line_logic}:activate()
			
		end
		
		line.render.onPass = render_line
		
		line.render:buildPipeline()
		
		return line
	end
	
	local old_ent_count, old_ent_active = -1, -1
	G.core.with( G.state:newFrame(), {
		step = function( this )
			if gs.getKey(VK.ESCAPE) then return false end
			
			local ent_count, ent_active = 0, 0
			
			G:forSubObjects(function(ent)
				ent_count = ent_count + 1
				if ent.state() then ent_active = ent_active + 1 end
				return true
			end)
			
			if old_ent_count ~= ent_count or old_ent_active ~= ent_active then
				print("ents in play, active: ", ent_count, ent_active)
			end
			old_ent_count, old_ent_active = ent_count, ent_active
			
			return true
		end
	})
	
	create_line():moveto( G )
	
	
	
end

if not gs.createWindow( "Godsource Engine Test [Forest]", 800, 600, -1, -1 ) then error("Creating Window... Failed!\n" )
else print( "Creating Window... Success") end
G.LoadHooks()
gs.init_success = true
